package com.oa.order.controller;

import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.oa.entity.ExtPageable;
import com.oa.entity.ExtjsAjaxResult;
import com.oa.order.dao.OrderDao;
import com.oa.order.dto.OrderDTO;
import com.oa.order.dto.OrderQueryDTO;
import com.oa.order.entity.Order;
import com.oa.order.service.OrderService;
import com.oa.order.util.MyPageImpl;
import com.oa.order.util.WorkflowVariable;
import com.oa.organization.dao.OrganizationDao;
import com.oa.system.dao.UserInfoDao;
import com.oa.system.entity.UserInfo;
import com.oa.util.SessionUtil;

@Controller
@RequestMapping(value = "/order")
public class OrderController {

	@Autowired
	private OrderService orderService;
	@Resource
	private UserInfoDao userInfoDao;
	@Resource
	private OrganizationDao organizationDao;
	@Resource
	private OrderDao orderDao;

	@RequestMapping("/findPage")
	public @ResponseBody Page<Order> findByOne(HttpSession session, ExtPageable pageable) {
		Page<Order> page = orderService.findByOne(SessionUtil.getUserName(session), pageable.getPageable());
		return page;
	}

	@RequestMapping(value = "/save")
	public @ResponseBody ExtjsAjaxResult save(Order order) {
		try {
			order.setApplyTime(new Date());
			orderService.save(order);
			return new ExtjsAjaxResult(true, "添加成功!");
		} catch (Exception e) {
			e.printStackTrace();
			return new ExtjsAjaxResult(false, "添加失败!");
		}
	}

	@RequestMapping(value = "/update")
	public @ResponseBody ExtjsAjaxResult update(Order order, Long orderId) {
		Order order1 = orderDao.findOne(orderId);
		if (order1.getState() == null || order1.getState().equals("已驳回")) {
			try {
				if (order1.getState().equals("已驳回")) {
					order.setState("待审批");
				}
				order.setApplyTime(new Date());
				orderService.save(order);
				return new ExtjsAjaxResult(true, "修改成功!");
			} catch (Exception e) {
				e.printStackTrace();
				return new ExtjsAjaxResult(false, "修改失败!");
			}
		} else {
			return new ExtjsAjaxResult(false, "此时不能修改该记录!");
		}
	}

	@RequestMapping(value = "/delete")
	public @ResponseBody ExtjsAjaxResult delete(Long[] orderIds) {
		try {
			for (Long orderId : orderIds) {
				Order order = orderDao.findOne(orderId);
				while (order.getState() == null || !order.getState().equals("已通过")) {
					orderService.delete(orderId);
					break;
				}
			}
			return new ExtjsAjaxResult(true, "删除成功!");
		} catch (Exception e) {
			e.printStackTrace();
			return new ExtjsAjaxResult(false, "删除失败!");
		}
	}

	@RequestMapping(value = "/order-list")
	public @ResponseBody Page<Order> findOrderByUserId(HttpSession session, ExtPageable pageable) {
		Page<Order> page = new PageImpl<Order>(new ArrayList<Order>(), pageable.getPageable(), 0);
		try {
			String userName = SessionUtil.getUserName(session);
			page = orderService.findByOne(userName, pageable.getPageable());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return page;
	}

	@RequestMapping("/find")
	public @ResponseBody Page<Order> findAll(OrderQueryDTO condetion, ExtPageable pageable)
			throws JsonParseException, JsonMappingException, IOException {
		Page<Order> page = orderService.findAll(OrderQueryDTO.getWhereClause(condetion), pageable.getPageable());
		return page;
	}

	/*-------------------------------------流程引擎web层------------------------------------------*/

	/**
	 * 启动流程
	 * 
	 * @param orderId
	 *            订餐信息Id
	 * @param session
	 *            通过会话获取登录用户(订餐人)
	 * @return
	 */
	@RequestMapping(value = "/start")
	public @ResponseBody ExtjsAjaxResult start(@RequestParam(name = "orderId") Long orderId, HttpSession session) {
		Order order = orderDao.findOne(orderId);
		if (order.getState() == null) {
			try {
				Map<String, Object> variables = new HashMap<String, Object>();
				UserInfo userInfo = userInfoDao.findOne(SessionUtil.getUserId(session));
				String role = userInfo.getRole().getRole();
				UserInfo userInfo1 = userInfoDao
						.findOne(organizationDao.findByName(userInfo.getDept().getName()).getLeadId());
				if (role.endsWith("STAFF")) {
					if (userInfo.getDept().getName().equals("人事部")) {
						variables.put("applyUserId", "administrativeAssistant");
						variables.put("hrManager", "HR_MANAGER");
					} else {
						variables.put("applyUserId", "deptClerk");
						variables.put("deptManager", userInfo1.getRole().getRole());
						variables.put("administrativeAssistant", "HR_STAFF");
						variables.put("hrManager", "HR_MANAGER");
					}
				}
				order.setState("待审批");
				orderService.save(order);
				orderService.startWorkflow(orderId, variables);
				return new ExtjsAjaxResult(true, "申请成功!");
			} catch (Exception e) {
				e.printStackTrace();
				return new ExtjsAjaxResult(false, "申请失败!");
			}
		} else if (order.getState().equals("已驳回")) {
			return new ExtjsAjaxResult(false, "请对订单进行修改!");
		} else if (order.getState().equals("已通过")) {
			return new ExtjsAjaxResult(false, "该订单已通过审批!");
		} else if (order.getState().equals("已取消")) {
			return new ExtjsAjaxResult(false, "该订单已取消!");
		} else {
			return new ExtjsAjaxResult(false, "该订单已经在申请中!");
		}
	}

	/**
	 * 查询待处理流程任务
	 * 
	 * @param pageable
	 *            分页对象
	 * @param session
	 *            通过会话获取登录用户(订餐人)
	 * @return
	 */
	@RequestMapping(value = "/findTasks")
	public @ResponseBody MyPageImpl<OrderDTO> findTodoTasks(HttpSession session, ExtPageable pageable) {
		Page<OrderDTO> page = new PageImpl<OrderDTO>(new ArrayList<OrderDTO>(), pageable.getPageable(), 0);
		try {
			page = orderService.findTodoTasks(SessionUtil.getUserId(session), pageable.getPageable());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new MyPageImpl<OrderDTO>(page.getContent(), pageable.getPageable(), page.getTotalElements(), true);
	}

	/**
	 * 签收任务
	 */
	@RequestMapping(value = "claim/{orderId}")
	public @ResponseBody ExtjsAjaxResult claim(@PathVariable("orderId") String taskId, HttpSession session,
			Long orderId) {
		try {
			Order order = orderDao.findOne(orderId);
			order.setState("审批中");
			orderService.save(order);
			orderService.claim(taskId, SessionUtil.getUserName(session));
			return new ExtjsAjaxResult(true, "任务签收成功!");
		} catch (Exception e) {
			e.printStackTrace();
			return new ExtjsAjaxResult(false, "任务签收失败!");
		}
	}

	/**
	 * 完成任务
	 * 
	 * @param orderId
	 * @return
	 */
	@RequestMapping(value = "complete/{orderId}")
	public @ResponseBody ExtjsAjaxResult complete(@PathVariable("orderId") String taskId, HttpSession session,
			WorkflowVariable var, Long orderId, Boolean pass, String refuseReason, String reapplyUserId) {
		try {
			Map<String, Object> variables = var.getVariableMap();
			Order order = orderDao.findOne(orderId);
			UserInfo userInfo = userInfoDao.findOne(SessionUtil.getUserId(session));
			if (order.getApprover() == null && !SessionUtil.getUserName(session).equals(reapplyUserId)) {
				order.setApprover(SessionUtil.getUserName(session));
			} else if (order.getApprover() != null && !SessionUtil.getUserName(session).equals(reapplyUserId)) {
				order.setApprover(order.getApprover() + " " + SessionUtil.getUserName(session));
			}
			order.setApprovalTime(new Date());
			if (pass == true) {
				if (userInfo.getRole().getRole().equals("HR_MANAGER")) {
					order.setState("已通过");
				}
				orderService.save(order);
				orderService.complete(taskId, variables);
				{
					if (SessionUtil.getUserName(session).equals(reapplyUserId)) {
						return new ExtjsAjaxResult(true, "已重新申请!");
					} else {
						return new ExtjsAjaxResult(true, "已通过申请!");
					}
				}
			} else if (SessionUtil.getUserName(session).equals(reapplyUserId)) {
				order.setState("已取消");
				orderService.save(order);
				orderService.complete(taskId, variables);
				return new ExtjsAjaxResult(false, "已取消申请!");
			} else {
				order.setState("已驳回");
				order.setRefuseReason(refuseReason);
				orderService.save(order);
				orderService.complete(taskId, variables);
				return new ExtjsAjaxResult(false, "已驳回申请!");
			}
		} catch (Exception e) {
			e.printStackTrace();
			return new ExtjsAjaxResult(false, "操作失败!");
		}
	}

	@RequestMapping(value = "/printExcel")
	public @ResponseBody ExtjsAjaxResult printExcel(Long[] orderIds, HttpServletResponse response) {
		try {
			// 第一步，创建一个webbook，对应一个Excel文件
			HSSFWorkbook wb = new HSSFWorkbook();
			// 第二步，在webbook中添加一个sheet,对应Excel文件中的sheet
			HSSFSheet sheet = wb.createSheet("订餐报表");
			// 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short
			HSSFRow row = sheet.createRow((int) 0);
			// 第四步，创建单元格，并设置值表头 设置表头居中
			HSSFCellStyle style = wb.createCellStyle();
			// style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式

			HSSFCell cell = row.createCell((short) 0);
			cell.setCellValue("部门");
			cell.setCellStyle(style);
			cell = row.createCell((short) 1);
			cell.setCellValue("晚餐");
			cell.setCellStyle(style);
			cell = row.createCell((short) 2);
			cell.setCellValue("宵夜");
			cell.setCellStyle(style);
			cell = row.createCell((short) 3);
			cell.setCellValue("次日早餐");
			cell.setCellStyle(style);
			cell = row.createCell((short) 4);
			cell.setCellValue("次日午餐");
			cell.setCellStyle(style);
			cell = row.createCell((short) 5);
			cell.setCellValue("日期");
			cell.setCellStyle(style);

			// 第四步，写入实体数据
			List<Order> list = new ArrayList<Order>();
			for (Long orderId : orderIds) {
				Order order = orderDao.findOne(orderId);
				list.add(order);
			}
			for (int i = 0; i < list.size(); i++) {
				row = sheet.createRow((int) i + 1);
				// 第五步，创建单元格，并设置值
				row.createCell((short) 0).setCellValue((String) list.get(i).getDepartmentName());
				row.createCell((short) 1).setCellValue((int) list.get(i).getDinner());
				row.createCell((short) 2).setCellValue((int) list.get(i).getNightSnack());
				row.createCell((short) 3).setCellValue((int) list.get(i).getBreakfast());
				row.createCell((short) 4).setCellValue((int) list.get(i).getLunch());
				row.createCell((short) 5)
						.setCellValue(new SimpleDateFormat("yyyy-mm-dd").format(list.get(i).getApprovalTime()));
			}

			// 第六步，将文件存到指定位置
			FileOutputStream fout = new FileOutputStream("D:/订餐报表.xls");
			wb.write(fout);
			fout.close();

			return new ExtjsAjaxResult(true, "操作成功,已保存到D:/订餐报表.xls!");
		} catch (Exception e) {
			e.printStackTrace();
			return new ExtjsAjaxResult(false, "操作失败!");
		}
	}
}